package com.zbkj.service.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zbkj.common.constants.SysConfigConstants;
import com.zbkj.common.constants.WeChatConstants;
import com.zbkj.common.constants.UserConstants;
import com.zbkj.common.exception.CrmebException;
import com.zbkj.common.model.order.StoreOrder;
import com.zbkj.common.model.user.User;
import com.zbkj.common.model.user.UserToken;
import com.zbkj.common.request.WechatShippingConfigRequest;
import com.zbkj.common.request.WechatShippingRequest;
import com.zbkj.common.response.WechatShippingResponse;
import com.zbkj.common.utils.RedisUtil;
import com.zbkj.common.utils.RestTemplateUtil;
import com.zbkj.service.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import java.util.HashMap;
import java.util.Map;

/**
 * 微信发货信息管理服务实现类
 * +----------------------------------------------------------------------
 * | CRMEB [ CRMEB赋能开发者，助力企业发展 ]
 * +----------------------------------------------------------------------
 * | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
 * +----------------------------------------------------------------------
 * | Licensed CRMEB并不是自由软件，未经许可不能去掉CRMEB相关版权
 * +----------------------------------------------------------------------
 * | Author: CRMEB Team <admin@crmeb.com>
 * +----------------------------------------------------------------------
 */
@Slf4j
@Service
public class WechatShippingServiceImpl implements WechatShippingService {

    @Autowired
    private SystemConfigService systemConfigService;
    
    @Autowired
    private WechatNewService wechatNewService;
    
    @Autowired
    private StoreOrderService storeOrderService;
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private UserTokenService userTokenService;
    
    @Autowired
    private RedisUtil redisUtil;
    
    @Autowired
    private RestTemplateUtil restTemplateUtil;

    private static final String WECHAT_SHIPPING_CONFIG_KEY = "wechat_shipping_config";
    private static final String WECHAT_SHIPPING_RETRY_KEY = "wechat_shipping_retry:";

    @Override
    public WechatShippingResponse uploadShippingInfo(WechatShippingRequest request) {
        log.info("微信发货信息上传开始，订单号：{}", request.getOrderKey());
        
        try {
            // 检查是否启用微信发货信息管理
            if (!isShippingEnabled()) {
                log.warn("微信发货信息管理未启用，订单号：{}", request.getOrderKey());
                return createErrorResponse(-1, "微信发货信息管理未启用");
            }

            // 获取微信小程序访问令牌
            String accessToken = wechatNewService.getMiniAccessToken();
            if (StrUtil.isBlank(accessToken)) {
                throw new CrmebException("获取微信访问令牌失败");
            }

            // 构建请求URL
            String url = StrUtil.format(WeChatConstants.WECHAT_SHIPPING_UPLOAD_URL + "?access_token={}", accessToken);

            // 构建请求参数
            Map<String, Object> params = buildUploadParams(request);

            // 发送请求
            String response = restTemplateUtil.postFromUrlencoded(url, 
                convertToMultiValueMap(params), null);
            log.info("微信发货信息上传响应：{}", response);

            // 解析响应
            JSONObject jsonObject = JSON.parseObject(response);
            WechatShippingResponse result = JSON.toJavaObject(jsonObject, WechatShippingResponse.class);

            if (result.getErrCode() == 0) {
                log.info("微信发货信息上传成功，订单号：{}", request.getOrderKey());
                // 清除重试缓存
                clearRetryCache(request.getOrderKey());
            } else {
                log.error("微信发货信息上传失败，订单号：{}，错误码：{}，错误信息：{}", 
                         request.getOrderKey(), result.getErrCode(), result.getErrMsg());
                // 记录重试信息
                recordRetryInfo(request.getOrderKey(), request);
            }

            return result;
        } catch (Exception e) {
            log.error("微信发货信息上传异常，订单号：{}", request.getOrderKey(), e);
            recordRetryInfo(request.getOrderKey(), request);
            return createErrorResponse(-1, "系统异常：" + e.getMessage());
        }
    }

    @Override
    public WechatShippingResponse getShippingStatus(String orderKey) {
        log.info("查询微信发货状态开始，订单号：{}", orderKey);
        
        try {
            // 获取微信小程序访问令牌
            String accessToken = wechatNewService.getMiniAccessToken();
            if (StrUtil.isBlank(accessToken)) {
                throw new CrmebException("获取微信访问令牌失败");
            }

            // 构建请求URL
            String url = StrUtil.format(WeChatConstants.WECHAT_SHIPPING_GET_ORDER_URL + "?access_token={}", accessToken);

            // 构建请求参数
            Map<String, Object> params = new HashMap<>();
            params.put("order_key", orderKey);

            // 发送请求
            String response = restTemplateUtil.postFromUrlencoded(url, 
                convertToMultiValueMap(params), null);
            log.info("查询微信发货状态响应：{}", response);

            // 解析响应
            JSONObject jsonObject = JSON.parseObject(response);
            return JSON.toJavaObject(jsonObject, WechatShippingResponse.class);
        } catch (Exception e) {
            log.error("查询微信发货状态异常，订单号：{}", orderKey, e);
            return createErrorResponse(-1, "系统异常：" + e.getMessage());
        }
    }

    @Override
    public WechatShippingResponse specialOrderReport(String orderKey) {
        log.info("微信特殊发货报备开始，订单号：{}", orderKey);
        
        try {
            // 获取微信小程序访问令牌
            String accessToken = wechatNewService.getMiniAccessToken();
            if (StrUtil.isBlank(accessToken)) {
                throw new CrmebException("获取微信访问令牌失败");
            }

            // 构建请求URL
            String url = StrUtil.format(WeChatConstants.WECHAT_SHIPPING_SPECIAL_URL + "?access_token={}", accessToken);

            // 构建请求参数
            Map<String, Object> params = new HashMap<>();
            params.put("order_key", orderKey);
            params.put("op_type", 1); // 1表示报备特殊发货

            // 发送请求
            String response = restTemplateUtil.postFromUrlencoded(url, 
                convertToMultiValueMap(params), null);
            log.info("微信特殊发货报备响应：{}", response);

            // 解析响应
            JSONObject jsonObject = JSON.parseObject(response);
            return JSON.toJavaObject(jsonObject, WechatShippingResponse.class);
        } catch (Exception e) {
            log.error("微信特殊发货报备异常，订单号：{}", orderKey, e);
            return createErrorResponse(-1, "系统异常：" + e.getMessage());
        }
    }

    @Override
    public WechatShippingConfigRequest getShippingConfig() {
        String configStr = systemConfigService.getValueByKey(WECHAT_SHIPPING_CONFIG_KEY);
        if (StrUtil.isBlank(configStr)) {
            // 返回默认配置
            WechatShippingConfigRequest config = new WechatShippingConfigRequest();
            config.setEnabled(false);
            config.setAutoUpload(true);
            config.setSpecialMode(1);
            config.setRetryTimes(3);
            config.setRetryInterval(30);
            return config;
        }
        return JSON.parseObject(configStr, WechatShippingConfigRequest.class);
    }

    @Override
    public Boolean updateShippingConfig(WechatShippingConfigRequest request) {
        String configStr = JSON.toJSONString(request);
        return systemConfigService.updateOrSaveValueByName(WECHAT_SHIPPING_CONFIG_KEY, configStr);
    }

    @Override
    public Boolean isShippingEnabled() {
        WechatShippingConfigRequest config = getShippingConfig();
        return config.getEnabled();
    }

    @Override
    public WechatShippingRequest buildShippingRequest(String orderNo, Integer logisticsType, 
                                                     String trackingNo, String expressCompany, String expressName) {
        // 根据订单号获取订单信息
        StoreOrder order = storeOrderService.getByOderId(orderNo);
        if (ObjectUtil.isNull(order)) {
            throw new CrmebException("订单不存在：" + orderNo);
        }

        // 获取用户信息和小程序openid
        User user = userService.getById(order.getUid());
        if (ObjectUtil.isNull(user)) {
            throw new CrmebException("用户不存在：" + order.getUid());
        }

        // 通过UserTokenService获取用户的小程序openid
        UserToken userToken = userTokenService.getTokenByUserId(order.getUid(), UserConstants.USER_TOKEN_TYPE_ROUTINE);
        if (ObjectUtil.isNull(userToken) || StrUtil.isBlank(userToken.getToken())) {
            throw new CrmebException("用户微信小程序openid不存在，用户ID：" + order.getUid());
        }

        // 构建微信发货请求对象
        WechatShippingRequest request = new WechatShippingRequest();
        request.setOrderKey(orderNo);
        request.setLogisticsType(logisticsType);
        request.setOpenid(userToken.getToken()); // 使用UserToken中的token作为openid
        request.setShipTime(System.currentTimeMillis());
        request.setUploadTime(System.currentTimeMillis());

        // 根据物流类型设置不同的参数
        if (logisticsType == 1) {
            // 快递发货
            request.setTrackingNo(trackingNo);
            request.setExpressCompany(expressCompany);
            request.setExpressName(expressName);
        } else if (logisticsType == 2) {
            // 同城配送
            request.setContact("同城配送");
        } else if (logisticsType == 3) {
            // 虚拟商品
            request.setContact("虚拟商品");
        }

        return request;
    }

    @Override
    @Async
    public void asyncUploadShippingInfo(WechatShippingRequest request) {
        log.info("异步上传微信发货信息，订单号：{}", request.getOrderKey());
        uploadShippingInfo(request);
    }

    @Override
    public Boolean retryUploadShippingInfo(String orderKey) {
        log.info("重试上传微信发货信息，订单号：{}", orderKey);
        
        try {
            // 从缓存中获取重试信息
            String retryKey = WECHAT_SHIPPING_RETRY_KEY + orderKey;
            String requestStr = redisUtil.get(retryKey);
            if (StrUtil.isBlank(requestStr)) {
                log.warn("未找到重试信息，订单号：{}", orderKey);
                return false;
            }

            WechatShippingRequest request = JSON.parseObject(requestStr, WechatShippingRequest.class);
            WechatShippingResponse response = uploadShippingInfo(request);
            
            return response.getErrCode() == 0;
        } catch (Exception e) {
            log.error("重试上传微信发货信息异常，订单号：{}", orderKey, e);
            return false;
        }
    }

    /**
     * 构建上传参数
     */
    private Map<String, Object> buildUploadParams(WechatShippingRequest request) {
        Map<String, Object> params = new HashMap<>();
        params.put("order_key", request.getOrderKey());
        params.put("logistics_type", request.getLogisticsType());
        params.put("ship_time", request.getShipTime());
        params.put("upload_time", request.getUploadTime());

        if (StrUtil.isNotBlank(request.getOpenid())) {
            params.put("payer_openid", request.getOpenid());
        }

        if (request.getLogisticsType() == 1) {
            // 快递发货
            if (StrUtil.isNotBlank(request.getTrackingNo())) {
                params.put("tracking_no", request.getTrackingNo());
            }
            if (StrUtil.isNotBlank(request.getExpressCompany())) {
                params.put("express_company", request.getExpressCompany());
            }
            if (StrUtil.isNotBlank(request.getExpressName())) {
                params.put("express_name", request.getExpressName());
            }
        }

        if (StrUtil.isNotBlank(request.getContact())) {
            params.put("contact", request.getContact());
        }

        return params;
    }

    /**
     * 创建错误响应
     */
    private WechatShippingResponse createErrorResponse(Integer errCode, String errMsg) {
        WechatShippingResponse response = new WechatShippingResponse();
        response.setErrCode(errCode);
        response.setErrMsg(errMsg);
        return response;
    }

    /**
     * 记录重试信息
     */
    private void recordRetryInfo(String orderKey, WechatShippingRequest request) {
        WechatShippingConfigRequest config = getShippingConfig();
        if (config.getRetryTimes() > 0) {
            String retryKey = WECHAT_SHIPPING_RETRY_KEY + orderKey;
            String requestStr = JSON.toJSONString(request);
            redisUtil.set(retryKey, requestStr, (long)(config.getRetryInterval() * config.getRetryTimes()));
        }
    }

    /**
     * 清除重试缓存
     */
    private void clearRetryCache(String orderKey) {
        String retryKey = WECHAT_SHIPPING_RETRY_KEY + orderKey;
        redisUtil.delete(retryKey);
    }

    /**
     * 将Map转换为MultiValueMap
     */
    private MultiValueMap<String, Object> convertToMultiValueMap(Map<String, Object> params) {
        MultiValueMap<String, Object> multiValueMap = new LinkedMultiValueMap<>();
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            multiValueMap.add(entry.getKey(), entry.getValue());
        }
        return multiValueMap;
    }
} 